
package FrontEnd;

import SBLib.IPAddresses;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import server.Server;
import server.ServerWorker;

/**
 * - Starts a Ping thread that will constantly be checking for the best RM server to relay messages to.
 * - Listens for client connections and spawns FEServerWorker threads to handle them. They will be constant connections with the client, however the 
 *      the connection to the best RM will not be constant as it will change as a new best RM becomes available (or the old best crashes)
 * @author BrandonNeal
 */
public class FEServer {
    
    public static int FEPort = 9999;
    public static int ServerPort = 9997;
    public int TIMEOUT=1000;
    public static String CurrentBestIp;
    
   // public static ArrayList<Socket> ToRemove = new ArrayList<Socket>();
    
    private final Vector<Socket> RMSockets = new Vector<Socket>();
    private Vector<ObjectOutputStream> RMOutputs = new Vector<ObjectOutputStream>();
    private Vector<ObjectInputStream> RMInputs = new Vector<ObjectInputStream>();
    
    
    public static void main(String[] args)
    {
        FEServer feServer = new FEServer();
        //feServer.InitiatePingThread();
        feServer.RunServer();
    }
    public void ConnectToRMServes()
    {
       for(String ip:IPAddresses.RMs) 
       {
           
            try
            {
                Socket sock = new Socket(ip, ServerPort);
                this.RMSockets.add(sock);
                ObjectOutputStream out = new ObjectOutputStream(sock.getOutputStream());
                out.flush();
                ObjectInputStream in = new ObjectInputStream(sock.getInputStream());
                this.RMOutputs.add(out);
                this.RMInputs.add(in);
                
            }
            catch (IOException ex) 
            {
                Logger.getLogger(FEServer.class.getName()).log(Level.SEVERE, null, ex);
            }
            
       }
    }
   /* public void InitiatePingThread()
    {
        Ping ping = new Ping();
        ping.start();
    }*/
    
    /**
     * - Listen from client
     * - Spawn FEServerWorker thread to handle the request.
     */
    public void RunServer()
    {
       this.ConnectToRMServes();
       try 
        {
            ServerSocket listenSocket = new ServerSocket(FEServer.FEPort);
            while(true)
            {
                Socket clientSocket = listenSocket.accept(); //Listen for connections
                System.out.println("FE connection Made");
                FEServerWorker feWorker = new FEServerWorker(clientSocket, RMSockets, RMInputs, RMOutputs);
            }
        }
        catch (IOException ex) 
        {
            Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
        }
        
    }
}
